#include "im.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int res_cb(char *filename, double* xres, double* yres, int* res_unit)
{
  *xres = 100;
  *yres = 100;
  *res_unit = IM_RES_DPI;
  return 0;
}

void setrescb(void)
{
  imRegisterCallback((imCallback)res_cb, IM_RESOLUTION_CB, IM_ALL);
}

char *StrUpper(char *s)
{
  int i, len = strlen(s);
  
  for (i = 0; i < len; i++) 
    s[i] = toupper(s[i]);
  
  return s;
}

void Usage(void)
{
  printf("Convert <input file> <output file> <output format> /RGB /C\n");
  printf("   Converts one Image File Format to another.\n");
  printf("<input file> - Image File Name\n");
  printf("<output file> - Image File Name\n");
  printf("<output format> - Valid options:\n");
  printf("                                 /BMP\n");
  printf("                                 /PCX\n");
  printf("                                 /GIF\n");
  printf("                                 /TIF\n");
  printf("                                 /RAS\n");
  printf("                                 /SGI\n");
  printf("                                 /TGA\n");
  printf("                                 /LED\n");
  printf("                                 /JPG\n");
  printf("/RGB - Force use of RGB Image.\n");
  printf("/C - Compress on output.\n");
}

int CheckParam(char* Param, const char* Value)
{
  if (Param[0] != '/')
    return 0;
  
  Param++;
  
  if (strstr(StrUpper(Param), Value) == NULL)
    return 0;
  
  return 1;
}

void ErrorMsg(const char* Func, int err)
{
  char Text[256];
  strcpy(Text, Func);
  strcat(Text, " - ");
  
  switch (err)
  {
  case IM_ERR_OPEN:
    strcat(Text, "Error Opening File.\n");
    break;
  case IM_ERR_READ:
    strcat(Text, "Error Reading File.\n");
    break;
  case IM_ERR_WRITE:
    strcat(Text, "Error Writing File.\n");
    break;
  case IM_ERR_TYPE:
    strcat(Text, "Image not Suported.\n");
    break;
  case IM_ERR_FORMAT:
    strcat(Text, "Invalid Format.\n");
    break;
  case IM_ERR_COMP:
    strcat(Text, "Compression not suported.\n");
    break;
  default:
    strcat(Text, "Unknown Error.\n");
  }
  
  printf(Text);
}

int main(int NumParam, char* ParamStr[])
{
  int w,h,t,f,err,pal_size, rgb = 0;
  unsigned char *red, *green, *blue, *map;
  long size, *color;
  
  if (NumParam < 2 || ParamStr[1][0] == '?' || NumParam < 4)
  {
    Usage();
    return 0;
  }
  
  if (CheckParam(ParamStr[3], "BMP"))
    f = IM_BMP;
  else if (CheckParam(ParamStr[3], "PCX"))
    f = IM_PCX;
  else if (CheckParam(ParamStr[3], "GIF"))
    f = IM_GIF;
  else if (CheckParam(ParamStr[3], "TIF"))
    f = IM_TIF;
  else if (CheckParam(ParamStr[3], "RAS"))
    f = IM_RAS;
  else if (CheckParam(ParamStr[3], "SGI"))
    f = IM_SGI;
  else if (CheckParam(ParamStr[3], "TGA"))
    f = IM_TGA;
  else if (CheckParam(ParamStr[3], "LED"))
    f = IM_LED;
  else if (CheckParam(ParamStr[3], "JPG"))
    f = IM_JPG;
  else
  {
    printf("Invalid Format Parameter.\n");
    return 0;
  }
  
  if (NumParam == 6)
  {
    if (CheckParam(ParamStr[5], "C"))
      f |= IM_DEFAULT;
    else if (CheckParam(ParamStr[5], "RGB"))
      rgb = 1;
  }
  else if (NumParam == 5)
  {
    if (CheckParam(ParamStr[4], "RGB"))
      rgb = 1;
    else if (CheckParam(ParamStr[4], "C"))
      f |= IM_DEFAULT;
  }
  
  printf("ImConvert %s\n", ParamStr[1]);
  
  err = imImageInfo(ParamStr[1], &w, &h, &t, &pal_size);
  
  if (err)
  {
    ErrorMsg("Image Info", err);
    return 0;
  }
  
  size = (long)w * (long)h;
  
  if (t == 0 || rgb)
  {
    red = (unsigned char *)malloc(size);
    green = (unsigned char *)malloc(size);
    blue = (unsigned char *)malloc(size);
    
    if (!red || !green || !blue)
    {
      printf("Insuficient Memory.\n");
      if (red) free(red);
      if (red) free(green);
      if (red) free(blue);
      return 0;
    }
    
    printf("Reading RGB...\n");
    
    err = imLoadRGB(ParamStr[1], red, green, blue);
    
    if (err)
    {
      ErrorMsg("Load RGB", err);
      free(red);
      free(green);
      free(blue);
      return 0;
    }
    
    printf("Writing RGB...\n");

    setrescb();
    
    err = imSaveRGB(w, h, f, red, green, blue, ParamStr[2]);
    
    if (err)
    {
      ErrorMsg("Save RGB", err);
      free(red);
      free(green);
      free(blue);
      return 0;
    }
    
    free(red);
    free(green);
    free(blue);
  }
  else
  {
    pal_size = 256;
    map = (unsigned char *)malloc(size);
    color = (long *)calloc(pal_size, 4);
    
    if (!map || !color)
    {
      printf("Insuficient Memory.\n");
      if (map) free(map);
      if (color) free(color);
      return 0;
    }
    
    printf("Reading Map...\n");
    
    err = imLoadMap(ParamStr[1], map, color);
    
    if (err)
    {
      ErrorMsg("Load Map", err);
      free(map);
      free(color);
      return 0;
    }
    
    printf("Writing Map...\n");

    setrescb();
    
    err = imSaveMap(w, h, f, map, pal_size, color, ParamStr[2]);
    
    if (err)
    {
      ErrorMsg("Save Map", err);
      free(map);
      free(color);
      return 0;
    }
    
    free(map);
    free(color);
  }
  
  return 1;
}


